home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-28 | 24.2 KB | 942 lines | [TEXT/MPS ] |
- /*
- File: ThreadClasses.cp
-
- Copyright: © 1991-1994 by Apple Computer, Inc.
- All rights reserved.
-
- Part of the AOCE Sample SMSAM Package. Consult the license
- which came with this software for your specific legal rights.
-
- */
-
-
-
- /***********************************|****************************************/
-
- #ifndef __BLJSTANDARDINCLUDES__
- #include "BLJStandardIncludes.h"
- #endif
-
- #ifndef __DEBUGGINGGEAR__
- #include <DebuggingGear.h>
- #endif
-
- #ifndef __FAILURE__
- #include "Failure.h"
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __GRAFPORTSAVER__
- #include "GrafPortSaver.h"
- #endif
-
- #ifndef __LIMITS__
- #include <Limits.h>
- #endif
-
- #ifndef __LOGWINDOW__
- #include "LogWindow.h"
- #endif
-
- #ifndef __OBJECTLIST__
- #include "ObjectList.h"
- #endif
-
- #ifndef __STRSTREAM__
- #include "StrStream.h"
- #endif
-
- #ifndef __THREADS__
- #include "Threads.h"
- #endif
-
- #ifndef __THREADCLASSES__
- #include "ThreadClasses.h"
- #endif
-
- // This macro 'references' a variable, so that a '# warning: variable not used' warning is not
- // generated during a compile. This macro should not cause any code to be generated.
- #ifndef __UNUSED__
- #define unused(x) ((void) &x)
- #define __UNUSED__
- #endif
-
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- class TThreadStatusWindow : public TLogWindow
- {
- public: TThreadStatusWindow ( short windowID );
- virtual ~TThreadStatusWindow ( );
-
- virtual void Show () const;
-
- virtual void DrawRow ( unsigned long whichRow ) const;
- virtual void RedrawSleeping ( ) const;
-
- virtual unsigned long GetRowCount () const;
- virtual unsigned long GetRowWidth ( ) const;
- };
-
- /***********************************|****************************************/
-
- #if debug
-
- Boolean IsThreadStatusDialogVisible ( );
- void ShowThreadStatusDialog ( );
- void HideThreadStatusDialog ( );
- Boolean HandleThreadStatusEvent ( EventRecord& event );
-
- TThreadStatusWindow* gThreadStatusWindow = nil;
- #endif
-
- /***********************************|****************************************/
-
- DeclareList(TThreadManagerThread,TThreadManagerThreadSharedList);
- ImplementList(TThreadManagerThread,TThreadManagerThreadSharedList,false);
-
- /***********************************|****************************************/
-
- unsigned long gTickWhenNextThreadNeedsToBeWoken = ULONG_MAX;
- TThreadManagerThreadSharedList gSleepingThreads;
-
- /***********************************|****************************************/
-
- void ChangeActiveThreadInThreadStatusWindow ( WindowPtr windowP, TThread * newThread );
- void UpdateThreadStatusWindow ( WindowPtr windowP );
-
- /***********************************|****************************************/
-
- inline unsigned long min ( unsigned long a, unsigned long b )
- {
- return ( a < b ) ? a : b ;
- }
-
- /***********************************|****************************************/
-
- Boolean IsThreadStatusDialogVisible ( )
- {
- return false;
- }
-
- /***********************************|****************************************/
-
- void ShowThreadStatusDialog ( )
- {
- #if 1
- if ( ! gThreadStatusWindow )
- {
- gThreadStatusWindow = new TThreadStatusWindow ( 2001 );
- gThreadStatusWindow->Show();
-
- gThreadStatusWindow->InsertRow( 1, TThread::GetThreadCount () );
- }
-
- gThreadStatusWindow->Show ();
- #endif
- }
-
- /***********************************|****************************************/
-
- void HideThreadStatusDialog ( )
- {
- if ( gThreadStatusWindow )
- {
- delete gThreadStatusWindow ;
- gThreadStatusWindow = nil;
- }
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- void TSleep ( unsigned long x )
- {
- unused(x);
- TThread* aThread = TThread::GetCurrentThread();
-
- if ( aThread )
- aThread->Sleep( x );
- }
-
- /***********************************|****************************************/
-
- void TYield()
- {
- TThread* aThread = TThread::GetCurrentThread();
-
- if ( aThread )
- aThread->Yield();
- }
-
- /***********************************|****************************************/
-
- void TSetRefCon(OSType x)
- {
- unused(x);
- }
-
- /***********************************|****************************************/
-
- OSType TGetRefCon()
- {
- TThread* aThread = TThread::GetCurrentThread();
-
- if ( aThread )
- return aThread->GetDescriptor();
- else
- return '\?\?\?\?';
- }
-
- /***********************************|****************************************/
-
- TThread* createThread(OSType name,
- void* proc, unsigned long stkSize,
- unsigned long p1, unsigned long p2,
- short execMode)
- {
- unused(stkSize); unused(execMode);
- return new TThreadManagerThread ( (FNULUL) proc, p1, p2, name );
- }
-
- /***********************************|****************************************/
-
- #if debug
- ostream& TThread::operator << ( ostream& s )
- { OSType threadDescriptor = GetDescriptor();
- s << "TThreadManagerThread:'";
- s.write ( (char*) & threadDescriptor, sizeof( threadDescriptor ) );
- s << "' " << flush;
-
- return s;
- }
- #endif
-
- /***********************************|****************************************/
-
- DeclareList ( TThread, TThreadList );
- ImplementList ( TThread, TThreadList, false );
-
- /***********************************|****************************************/
-
- TThread * TThread::gCurrentThread = nil;
- TThread * TThread::gThreadList = nil;
-
- TThreadList gThreadStatusWindowList;
-
- /***********************************|****************************************/
-
-
- /***********************************|****************************************/
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- static pascal void ThreadPBCallAsyncCompletion ( )
- {
- }
-
- /***********************************|****************************************/
-
- typedef pascal OSErr (*FNPBB)(ParmBlkPtr, Boolean);
-
- /***********************************|****************************************/
-
- OSErr ThreadPBCallAsync ( FNPBB functionToCall, ParmBlkPtr pb )
- {
- typedef struct {
- ParmBlkPtr thePB;
- TThread* theThread;
- } ThreadInfo;
-
- ThreadInfo info;
-
- info.thePB = pb;
- info.theThread = TThread::GetCurrentThread();
-
- info.theThread->BeginCritical ();
- OSErr err = ( *functionToCall ) ( pb, false );
- info.theThread->EndCritical ();
-
- return err;
- }
-
- /***********************************|****************************************/
-
- TThread::TThread ( )
- {
- // Create a thread, and insert this thread descriptor into the linked list of
- // all threads.
- fNext = gThreadList;
- gThreadList = this;
-
- // Insert this thread into the thread status window.
- #if debug
- gThreadStatusWindowList.Append ( this );
- if ( gThreadStatusWindow )
- gThreadStatusWindow->InsertRow ( 1 );
- #endif
- }
-
- /***********************************|****************************************/
-
- TThread::~TThread ( )
- {
- // Remove this thread from the linked list of all threads.
- if ( gThreadList == this )
- {
- gThreadList = this->fNext;
- }
- else
- { TThread *prevThread = gThreadList;
-
- while ( prevThread && ( prevThread->fNext != this ) )
- prevThread = prevThread->fNext;
-
- if ( prevThread )
- prevThread->fNext = prevThread->fNext->fNext;
- }
-
- #if debug
- gThreadStatusWindowList.Remove ( this );
- #endif
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- pascal unsigned long TThreadInstantiationWrapper ( TThreadManagerThread* thread )
- {
- ::SetExceptionChain ( (void*) nil );
-
- TRY
- (*thread->fThreadEntry ) ( (unsigned long) thread->fParam1, (unsigned long) thread->fParam2 );
-
- EXCEPTION
- keith << "TThread::Failure to top level of thread "; OutputOSType ( keith, thread->fDescriptor ); keith << endl;
-
- ENDEXCEPTION
-
- return 0;
- }
-
- /***********************************|****************************************/
-
- pascal void TThreadManagerThread::ThreadManagerSwitchInProc ( ThreadID /* threadBeingSwitched */, void* switchProcParam )
- {
- TThreadManagerThread* thread = ( TThreadManagerThread *) switchProcParam;
-
- if ( thread )
- { unsigned long savedA5 = SetA5 ( thread->fA5 );
-
- ::SetExceptionChain ( thread->GetExceptionChain() );
-
- gCurrentThread = thread;
-
- #if 0
- if ( gThreadStatusWindow )
- gThreadStatusWindow->InvalidateRow ( gThreadStatusWindowList.Find ( thread ) );
- #endif
-
- SetA5 ( savedA5 );
- }
- }
-
- /***********************************|****************************************/
-
- pascal void TThreadManagerThread::ThreadManagerSwitchOutProc ( ThreadID /* threadBeingSwitched */, void* switchProcParam )
- {
- TThreadManagerThread * thread = ( TThreadManagerThread *) switchProcParam;
-
- if ( thread )
- { unsigned long savedA5 = SetA5 ( thread->fA5 );
-
- thread->SetExceptionChain ( ::GetExceptionChain() );
- ::SetExceptionChain ( nil );
-
- #if 0
- if ( gThreadStatusWindow )
- gThreadStatusWindow->InvalidateRow ( gThreadStatusWindowList.Find ( thread ) );
- #endif
-
- SetA5 ( savedA5 );
- }
- }
-
- /***********************************|****************************************/
-
- pascal void TThreadManagerThread::TThreadManagerThreadTerminationProc ( ThreadID /* threadID */, void * terminationProcParam )
- {
- TThreadManagerThread * thread = ( TThreadManagerThread * ) terminationProcParam;
-
- if ( thread )
- { unsigned long savedA5 = SetA5 ( thread->fA5 );
-
- #if debug
- if ( gThreadStatusWindow )
- gThreadStatusWindow->DeleteRow ( gThreadStatusWindowList.Find ( thread ) );
- #endif
-
- // Change the thread so that our destructor won't try to delete it.
- thread->fThreadID = kNoThreadID;
- delete thread;
-
- SetA5 ( savedA5 );
- }
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- TThreadManagerThread::TThreadManagerThread ( FNULUL proc, unsigned long param1, unsigned long param2, OSType descriptor ) :
- fDescriptor ( descriptor ),
- fExceptionChainTop ( nil ),
- fA5 ( SetCurrentA5 () )
- {
- fThreadEntry = proc;
-
- fParam1 = param1;
- fParam2 = param2;
-
- OSErr err = NewThread ( kCooperativeThread, (ThreadEntryProcPtr) &TThreadInstantiationWrapper, this, 0, kCreateIfNeeded, nil, &fThreadID );
- SetThreadSwitcher ( fThreadID, (ThreadSwitchProcPtr) ThreadManagerSwitchInProc, (void*) this, true );
- SetThreadSwitcher ( fThreadID, (ThreadSwitchProcPtr) ThreadManagerSwitchOutProc, (void*) this, false );
- SetThreadTerminator ( fThreadID, (ThreadTerminationProcPtr) TThreadManagerThreadTerminationProc, (void*) this );
-
- if ( err )
- keith << "TThreadManagerThreadTThread(), err = " << err << endl;
- }
-
- /***********************************|****************************************/
-
- TThreadManagerThread::TThreadManagerThread ( OSType descriptor ) :
- fDescriptor ( descriptor ),
- fExceptionChainTop ( nil ),
- fThreadID ( kApplicationThreadID ),
- fThreadEntry ( nil ),
- fParam1 ( 0 ),
- fParam2 ( 0 ),
- fA5 ( SetCurrentA5 () )
- {
- OSErr err = ::GetCurrentThread ( & fThreadID);
-
- SetThreadSwitcher ( fThreadID, (ThreadSwitchProcPtr) ThreadManagerSwitchInProc, (void*) this, true );
- SetThreadSwitcher ( fThreadID, (ThreadSwitchProcPtr) ThreadManagerSwitchOutProc, (void*) this, false );
- SetThreadTerminator ( fThreadID, (ThreadTerminationProcPtr) TThreadManagerThreadTerminationProc, (void*) this );
- }
-
- /***********************************|****************************************/
-
- TThreadManagerThread::~TThreadManagerThread ( )
- {
- // Make sure we're not in the list of sleeping threads.
- gSleepingThreads.Remove ( this );
-
- // And delete our actual thread if it hasn't already been deleted.
- ThreadID threadID = fThreadID;
- fThreadID = kNoThreadID;
- if ( threadID != kNoThreadID )
- DisposeThread ( threadID, 0, true );
- }
-
- /***********************************|****************************************/
-
- static unsigned long TicksUntil ( unsigned long tick )
- {
- unsigned long now = TickCount ();
-
- if ( tick < now )
- return 0;
- else
- return tick - now;
- }
-
- /***********************************|****************************************/
-
- #if debug
- ostream& TThreadManagerThread::operator << ( ostream& s )
- { OSType threadDescriptor = GetDescriptor();
- s << "TThread:'";
- s.write ( (char*) & threadDescriptor, sizeof( threadDescriptor ) );
- s << "' ";
-
- // Display the state of the thread.
- ThreadState state;
- OSErr err = GetThreadState ( fThreadID, & state );
- if ( err == noErr )
- {
- switch ( state )
- {
- case kReadyThreadState:
- s << "Ready ";
- break;
-
- case kStoppedThreadState:
- s << "Sleeping (" <<
- TicksUntil ( fWakeThreadAfter ) / 60 <<
- " secs longer) ";
- break;
-
- case kRunningThreadState:
- s << "Running ";
- break;
-
- default:
- s << "(Unknown state=" << state << ") ";
- break;
- };
- }
- else
- {
- s << "(Error " << err << " getting state) ";
- }
-
- // Display the amount of stack space available to the thread.
- unsigned long stackSize;
- err = ThreadCurrentStackSpace ( fThreadID, & stackSize );
- s << " Stack:" << stackSize << " " << (char) 0;
-
- return s;
- }
- #endif
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::Sleep ( unsigned long howLongToSleep )
- { unused(howLongToSleep);
- unsigned long sleepUntil = TickCount() + howLongToSleep;
-
- if ( TThread::GetCurrentThread() == this ) {
- #if debug
- if ( gThreadStatusWindow )
- gThreadStatusWindow->InvalidateRow ( gThreadStatusWindowList.Find ( this ) );
- #endif
-
- ThreadBeginCritical ();
-
- fWakeThreadAfter = TickCount() + howLongToSleep;
-
- gTickWhenNextThreadNeedsToBeWoken = min ( gTickWhenNextThreadNeedsToBeWoken, fWakeThreadAfter );
- gSleepingThreads.Append ( this );
-
- SetThreadStateEndCritical ( fThreadID, kStoppedThreadState, kNoThreadID );
-
- #if debug
- if ( gThreadStatusWindow )
- gThreadStatusWindow->DrawRow ( gThreadStatusWindowList.Find ( this ) );
- #endif
- }
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::Yield ( )
- {
- if ( TThread::GetCurrentThread() == this ) {
-
- OSErr err = YieldToAnyThread ();
- if ( err )
- keithDB ( "TThreadManagerThread::YieldToAnyThread(), err=" << err );
- }
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::Wake ( )
- {
- SetThreadState ( fThreadID, kReadyThreadState, kNoThreadID );
- gSleepingThreads.Remove ( this );
-
- #if debug
- if ( gThreadStatusWindow )
- gThreadStatusWindow->DrawRow ( gThreadStatusWindowList.Find ( this ) );
- #endif
- }
-
- /***********************************|****************************************/
-
- void* TThreadManagerThread::GetExceptionChain (void) const
- {
- return fExceptionChainTop;
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::SetExceptionChain(void * chainTop )
- {
- fExceptionChainTop = chainTop;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- TThread* TThread::GetCurrentThread ( )
- {
- return gCurrentThread;
- }
-
- /***********************************|****************************************/
-
- void TThread::YieldCurrentThread ( TThread* threadToYieldTo )
- {
- unused(threadToYieldTo);
-
- GetCurrentThread()->Yield();
- }
-
- /***********************************|****************************************/
-
- unsigned long TThread::GetCurrentThreadStackSpace ()
- { unsigned long stackSize = 0;
-
- OSErr err = ThreadCurrentStackSpace ( kCurrentThreadID, &stackSize );
-
- if ( err )
- keith << "TThread::GetCurrentThreadStackSpace(), err = " << err << endl;
-
- return stackSize;
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::BeginCritical ( )
- {
- ThreadBeginCritical ();
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::EndCritical ( )
- {
- ThreadEndCritical ();
- }
-
- /***********************************|****************************************/
-
- OSType TThreadManagerThread::GetDescriptor ()
- {
- return fDescriptor;
- }
-
- /***********************************|****************************************/
-
- unsigned long TThread::GetThreadCount ( )
- {
- TThread* thread = gThreadList;
- unsigned long threadCount = 0;
-
- while ( thread )
- {
- thread = thread->fNext;
- ++threadCount;
- }
-
- return threadCount;
- }
-
- /***********************************|****************************************/
-
- TThread * TThread::GetThread ( unsigned long index )
- {
- TThread * result = gThreadList;
- while ( result && ( index > 1 ) ) {
- result = result->fNext;
- index --;
- }
-
- return result;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- class TThreadManagerMainApplicationThread : public TThreadManagerThread
- {
- public:
- TThreadManagerMainApplicationThread ( );
- virtual ~TThreadManagerMainApplicationThread ();
-
- virtual void Sleep ( unsigned long howLongToSleep = 0 );
- virtual void Yield ( );
- virtual void Wake ( );
-
- virtual OSType GetDescriptor();
- };
-
- /***********************************|****************************************/
-
- TThreadManagerMainApplicationThread::TThreadManagerMainApplicationThread () :
- TThreadManagerThread ( 'MAIN' )
- {
- fThreadID = kApplicationThreadID;
-
- // The main thread doesn't need a terminator
- SetThreadTerminator ( fThreadID, (ThreadTerminationProcPtr) nil, (void*) this );
- gCurrentThread = this;
- }
-
- /***********************************|****************************************/
-
- TThreadManagerMainApplicationThread::~TThreadManagerMainApplicationThread ()
- {
- // DebugStr ("\pTThreadManagerMainApplicationThread::~TThreadManagerMainApplicationThread()");
- fThreadID = 0;
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerMainApplicationThread::Sleep ( unsigned long /* howLongToSleep */ )
- {
- if ( gThreadStatusWindow )
- gThreadStatusWindow->RedrawSleeping ();
-
- // The Main Event Loop thread should never get put to sleep.
- // Instead, just yield to someone else.
- YieldToAnyThread ();
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerMainApplicationThread::Yield ( )
- {
- if ( gThreadStatusWindow )
- gThreadStatusWindow->RedrawSleeping ();
-
- if ( TThread::GetCurrentThread() == this ) {
- YieldToAnyThread ();
- }
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerMainApplicationThread::Wake ( )
- {
- SetThreadState ( fThreadID, kReadyThreadState, kNoThreadID );
- }
-
- /***********************************|****************************************/
-
- OSType TThreadManagerMainApplicationThread::GetDescriptor ()
- {
- return 'MAIN';
- }
-
- /***********************************|****************************************/
-
- TThread* gMainApplicationThread = nil;
-
- /***********************************|****************************************/
-
- void CreateMainApplicationThread ()
- {
- // Verify that the threads manager is installed.
- long value;
- if ( ( Gestalt ( gestaltThreadMgrAttr, &value ) != noErr ) || ( (value & ( 1 << gestaltThreadMgrPresent)) == 0 ) )
- {
- #if debug
- DebugStr ("\pThe Threads Manager extension must be installed to use this gateway.");
- #endif
-
- ExitToShell();
- }
-
- gMainApplicationThread = new TThreadManagerMainApplicationThread();
- }
-
- /***********************************|****************************************/
-
- void TThreadManagerThread::WakeUpSleepingThreadsTask ( )
- {
- if ( gTickWhenNextThreadNeedsToBeWoken <= TickCount() )
- {
- // If we're currently in some thread,
- if ( GetCurrentThread() )
- {
- // Then don't let anything weird happen for a little while.
- GetCurrentThread()->BeginCritical () ;
-
- // Step through all of the threads, waking any thread that should
- // be woken up.
- gTickWhenNextThreadNeedsToBeWoken = LONG_MAX;
- for ( unsigned long i = gSleepingThreads.Count(); i > 0; -- i )
- { TThreadManagerThread * thread = gSleepingThreads.Get ( i );
-
- if ( thread && thread->fWakeThreadAfter <= TickCount() )
- thread->Wake ( );
- else
- gTickWhenNextThreadNeedsToBeWoken = min ( thread->fWakeThreadAfter, gTickWhenNextThreadNeedsToBeWoken );
- }
-
- // And let the world be happy again.
- GetCurrentThread()->EndCritical ();
- }
- }
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- void ShowAllThreadStatus ( ostream& s )
- {
- s << "Thread Status: (" << TThread::GetThreadCount() << " total, " <<
- gSleepingThreads.Count() << " sleeping)" << endl;
-
- for ( unsigned long i = 1; i <= TThread::GetThreadCount(); ++ i )
- {
- TThread * t = TThread::GetThread ( i );
-
- if ( t )
- {
- s << " ";
- s.width(3);
- s << i << ") "; t->operator << ( s ); s << endl;
- }
- }
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
- /***********************************|****************************************/
-
-
- /***********************************|****************************************/
-
- TThreadStatusWindow::TThreadStatusWindow ( short windowID ) :
- TLogWindow ( windowID )
- {
- }
-
- /***********************************|****************************************/
-
- TThreadStatusWindow::~TThreadStatusWindow ()
- {
- }
-
- /***********************************|****************************************/
-
- void TThreadStatusWindow::Show () const
- {
- TLogWindow::Show ();
-
- CGrafPortSaver portSaver ( GetWindowPtr () );
- TextFont ( 1 );
- TextSize ( 10 );
- TextFace ( 0 );
- TextMode ( srcCopy );
- }
-
- /***********************************|****************************************/
-
- unsigned long TThreadStatusWindow::GetRowCount () const
- {
- return TThread::GetThreadCount () + 1;
- }
-
- /***********************************|****************************************/
-
- void TThreadStatusWindow::DrawRow ( unsigned long whichRow ) const
- {
- CGrafPortSaver saver ( fDebugWindowPtr );
- Rect r = GetRectForRow ( whichRow );
- short x = r.left;
- short baseY = r.bottom - 2;
-
- const short kDescriptorOffset = 2;
- const short kStateOffset = 50;
- const short kSleepingUntilOffset = 100;
- const short kStackSizeOffset = 160;
-
- if ( whichRow == 1 )
- {
- DrawString ( x + kDescriptorOffset, baseY, "\pThread" );
- EraseLineToDrawString ( x + kStateOffset, baseY, "\pState" );
- EraseLineToDrawString ( x + kSleepingUntilOffset, baseY, "\pUntil" );
- EraseLineToDrawString ( x + kStackSizeOffset, baseY, "\pStack space" );
- EraseLineToDrawString ( (short) x + GetRowWidth(), baseY, "\p" );
-
- return;
- }
-
- #if 1
-
- TThreadManagerThread* t = (TThreadManagerThread*) TThread::GetThread ( whichRow - 1);
-
- if ( t )
- {
- MoveTo ( x + kDescriptorOffset, baseY );
- DrawText ( (Ptr) & t->fDescriptor , 0, sizeof ( t->fDescriptor ) );
-
- ThreadState state;
-
- if ( GetThreadState ( t->fThreadID, & state ) != noErr )
- state = (ThreadState) 0xffff;
-
- switch ( state )
- {
- case kRunningThreadState:
- EraseLineToDrawString ( x + kStateOffset, baseY, "\pRunning" );
- break;
-
- case kReadyThreadState:
- EraseLineToDrawString ( x + kStateOffset, baseY, "\pReady");
- break;
-
- case kStoppedThreadState:
- EraseLineToDrawString ( x + kStateOffset, baseY, "\pStopped" );
-
- EraseLineToDrawNumber ( x + kSleepingUntilOffset, baseY, TicksUntil ( t->fWakeThreadAfter ) / 60 );
- DrawString ("\p secs");
-
- break;
-
- default:
- EraseLineToDrawString ( x + kStateOffset, baseY, "\p?" );
- break;
- };
-
- unsigned long stackSize;
- if ( ThreadCurrentStackSpace ( t->fThreadID, & stackSize ) == noErr )
- EraseLineToDrawNumber ( x + kStackSizeOffset, baseY, stackSize );
- }
- else
- {
- EraseRect ( &r );
- }
-
- #else
-
- TThread* t;
-
- t = TThread::GetThread ( whichRow );
-
- if ( t )
- { strstream text;
-
- t->operator << ( text );
- DrawText ( text.str(), 0, strlen ( text.str() ) );
- }
- #endif
- }
-
- /***********************************|****************************************/
-
- void TThreadStatusWindow::RedrawSleeping ( ) const
- {
- for ( unsigned int i = 1; i <= GetRowCount() ; ++ i )
- DrawRow ( i );
- }
-
- /***********************************|****************************************/
-
- unsigned long TThreadStatusWindow::GetRowWidth ( ) const
- {
- return 300;
- }
-
- /***********************************|****************************************/
-